package com.android.webttest.utils;

import android.content.Context;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
import android.util.Base64;

import java.security.KeyStore;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import android.content.SharedPreferences;

public class TokenManager {

    private static final String KEY_ALIAS = "authTokenKey";
    private static final String PREFS_NAME = "MyPrefs";
    private static final String ENCRYPTED_TOKEN_KEY = "encryptedAuthToken";
    private static final String IV_KEY = "iv";

    private static KeyStore keyStore;

    /**
     * 初始化 KeyStore 和生成密钥
     * @param context
     * @throws Exception
     */
    public static void init(Context context) throws Exception {
        keyStore = KeyStore.getInstance("AndroidKeyStore");
        keyStore.load(null);

        if (!keyStore.containsAlias(KEY_ALIAS)) {
            KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
            keyGenerator.init(new KeyGenParameterSpec.Builder(KEY_ALIAS,
                    KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                    .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
                    .setUserAuthenticationRequired(false)
                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                    .build());
            keyGenerator.generateKey();
        }
    }

    /**
     * 加密并存储 token
     * @param context
     * @param token
     * @throws Exception
     */
    public static void encryptAndStoreToken(Context context, String token) throws Exception {
        SecretKey secretKey = (SecretKey) keyStore.getKey(KEY_ALIAS, null);
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] iv = cipher.getIV();
        byte[] encryptedToken = cipher.doFinal(token.getBytes());

        SharedPreferences sharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString(ENCRYPTED_TOKEN_KEY, Base64.encodeToString(encryptedToken, Base64.DEFAULT));
        editor.putString(IV_KEY, Base64.encodeToString(iv, Base64.DEFAULT));
        editor.apply();
    }

    /**
     * 读取并解密 token
     * @param context
     * @return
     * @throws Exception
     */
    public static String readAndDecryptToken(Context context) throws Exception {
        SharedPreferences sharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
        String storedEncryptedToken = sharedPreferences.getString(ENCRYPTED_TOKEN_KEY, null);
        String storedIv = sharedPreferences.getString(IV_KEY, null);

        if (storedEncryptedToken == null || storedIv == null) {
            return null;
        }

        byte[] decodedEncryptedToken = Base64.decode(storedEncryptedToken, Base64.DEFAULT);
        byte[] decodedIv = Base64.decode(storedIv, Base64.DEFAULT);

        SecretKey secretKey = (SecretKey) keyStore.getKey(KEY_ALIAS, null);
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        cipher.init(Cipher.DECRYPT_MODE, secretKey, new GCMParameterSpec(128, decodedIv));
        byte[] decryptedTokenBytes = cipher.doFinal(decodedEncryptedToken);
        return new String(decryptedTokenBytes);
    }
}

